package application

import (
	"bytes"
	"cloud_android_backend/api/common"
	"cloud_android_backend/pkg/middleware/authorization"
	"cloud_android_backend/pkg/models/application"
	model "cloud_android_backend/pkg/models/users"
	"cloud_android_backend/pkg/utils"
	"encoding/json"
	errors2 "errors"
	"fmt"

	// "io"
	"io/ioutil"
	"log"
	"mime/multipart"
	"net/http"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/golang/glog"
	"github.com/jinzhu/gorm"
	"modules.tenxcloud.com/common/composite"
	rb "modules.tenxcloud.com/common/middleware"
)

func Register(application *gin.RouterGroup) {

	//application.GET("/video/list", authorization.TokenCheck, GetVideoList)
	//application.POST("/video/upload", rb.RequestBody, authorization.TokenCheck, UploadVideo)
	application.POST("/app/create", rb.RequestBody, authorization.TokenCheck, CreateApp)
	application.POST("/app/update/:appId", rb.RequestBody, authorization.TokenCheck, UpdateApp)
	application.POST("/app/delete/:appId", rb.RequestBody, authorization.TokenCheck, DeleteApp)
	application.GET("/app/info/:appId", rb.RequestBody, authorization.TokenCheck, GetAppDetail)
	application.POST("/app/preview", rb.RequestBody, authorization.TokenCheck, func(c *gin.Context) {
		c.Set("isPreview", "true")
	}, CreateApp)
	application.GET("/app/list", authorization.TokenCheck, GetAppList)
	application.GET("/knowledge/list", authorization.TokenCheck, GetKnowledgeList)
	application.POST("/knowledge/create", rb.RequestBody, authorization.TokenCheck, CreateDefaultKbHandler)
	application.POST("/knowledge/upload", authorization.TokenCheck, UploadFilesToKbHandler)
	application.GET("/knowledge/kblist", authorization.TokenCheck, ListKnowledgeBaseHandler)
	application.POST("/knowledge/kbfiles", authorization.TokenCheck, ListKnowledgeBaseFilesHandler)
	application.POST("/knowledge/deletefile", authorization.TokenCheck, DeleteKnowledgeBaseFilesHandler)
	application.POST("/knowledge/clean", authorization.TokenCheck, CleanFilesByStatusHandler)
	application.POST(("knowledge/deletekb"), authorization.TokenCheck, DeleteKbHandler)
	application.POST(("knowledge/rename"), authorization.TokenCheck, RenameKbHandler)
	application.GET("/model/list", authorization.TokenCheck, GetModelList)
	application.GET("/voice/list", authorization.TokenCheck, GetVoiceList)
}
func Register2(application *gin.RouterGroup) {
	application.GET("/app/info/:appId", rb.RequestBody, GetAppDetail)
}

type AppForm struct {
	application.Application
	KnowledgeId []int `json:"knowledge_ids"`
}

func CreateApp(c *gin.Context) {
	li, exists := c.Get(authorization.LoginUserKey)
	if !exists {
		c.AbortWithStatusJSON(common.ErrorResponse("get user from content failed"))
		return
	}
	current := li.(*model.User)
	// 从请求体中解析应用表单数据
	body, _ := c.Get(rb.RequestBodyKey)
	appForm := AppForm{}
	if err := json.Unmarshal(body.([]byte), &appForm); err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}
	// 获取数据库连接
	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
	}
	// 获取模型信息
	modelInfo := application.Model{Id: appForm.ModelId}
	err = modelInfo.GetById(db)
	if err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}
	// 生成短UID（用户ID的前缀部分）
	shortUid := strings.ToLower(strings.Replace(current.UserID[:len(current.UserID)-4], "UID-", "", 1))
	const testUserId = "zzp"
	// 创建默认知识库
	//这个地方的代码需要修正
	defaultKb, err := utils.CreateDefaultKb(shortUid, testUserId)
	if err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}
	kbsList := []string{defaultKb}
	for _, kb := range appForm.KnowledgeId {
		kb1 := application.Knowledge{Id: kb}
		err = kb1.GetById(db)
		if err != nil {
			glog.Error(err)
			c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
			return
		}
		kbsList = append(kbsList, kb1.KnowledgeId)
	}
	//
	// 创建机器人
	bot, err := CreateBot(shortUid, appForm.AppName, appForm.RoleSet, appForm.WelcomeMsg, kbsList)
	if err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}
	// 更新机器人配置
	err = UpdateBot(UpdateBotReq{
		UserId:  shortUid,
		BotId:   bot,
		Setting: appForm.RoleSet,
		BotName: appForm.AppName,
		ApiBase: modelInfo.ApiBase,
		ApiKey:  modelInfo.ApiKey,
		Model:   modelInfo.Model,
	})
	if err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}
	//{
	//    "user_id": "zzpp",
	//    "bot_name": "唐僧",
	//    "prompt_setting":"- 你是唐僧，一个耐心、友好、专业的机器人，能够回答用户的各种问题，如果用户问你的身份，你要回答你是唐僧。- 根据知识库内的检索结果，以清晰简洁的表达方式回答问题。- 如果给定的检索结果无法回答问题，可以利用你的知识尽可能回答用户的问题。",
	//    "welcome_message":"您好，我是您的专属机器人，请问有什么可以帮您呢？",
	//     "kb_ids": ["KB73162d737fd74763bc72e75382ea81dd_240625"]
	//
	//}

	db.Transaction(func(tx *gorm.DB) error {
		app := application.Application{
			AppName:     appForm.AppName,
			RoleId:      appForm.RoleId,
			RoleSet:     appForm.RoleSet,
			MultiConver: appForm.MultiConver,
			WelcomeMsg:  appForm.WelcomeMsg,
			UserId:      current.UserID,
			ModelId:     appForm.ModelId,
			VoiceId:     appForm.VoiceId,
			CreatedAt:   time.Time{},
			UpdatedAt:   time.Time{},
			BotId:       bot,
			Status:      1,
		}
		if _, ok := c.Get("isPreview"); ok {
			app.Status = 0
		}
		if err := app.Create(tx); err != nil {
			glog.Error(err)
			c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
			return err
		}
		for _, knowledgeId := range appForm.KnowledgeId {
			appKnowledgeRelate := application.AppKnowledgeRelate{
				AppId:       app.Id,
				KnowledgeId: knowledgeId,
			}
			if err := appKnowledgeRelate.Create(tx); err != nil {
				glog.Error(err)
				c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
				return err
			}
		}
		return nil
	})
	c.JSON(http.StatusOK, common.SuccessResponse(appForm))
}
func UpdateApp(c *gin.Context) {
	li, exists := c.Get(authorization.LoginUserKey)
	if !exists {
		c.AbortWithStatusJSON(common.ErrorResponse("get user from context failed"))
		return
	}
	current := li.(*model.User)

	appIdStr := c.Param("appId")
	appId, err := strconv.Atoi(appIdStr)
	if err != nil {
		c.AbortWithStatusJSON(common.ErrorResponse("invalid app ID"))
		return
	}

	body, _ := c.Get(rb.RequestBodyKey)
	appForm := AppForm{}
	if err := json.Unmarshal(body.([]byte), &appForm); err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}

	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}

	db.Transaction(func(tx *gorm.DB) error {
		app := application.Application{
			Id:          appId,
			UserId:      current.UserID,
			ModelId:     appForm.ModelId,
			VoiceId:     appForm.VoiceId,
			WelcomeMsg:  appForm.WelcomeMsg,
			RoleId:      appForm.RoleId,
			RoleSet:     appForm.RoleSet,
			MultiConver: appForm.MultiConver,
			AppName:     appForm.AppName,
		}
		if err := app.Update(tx); err != nil {
			glog.Error(err)
			c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
			return err
		}

		// 删除旧的知识库关联
		if err := tx.Where("app_id = ?", appId).Delete(&application.AppKnowledgeRelate{}).Error; err != nil {
			glog.Error(err)
			c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
			return err
		}

		// 创建新的知识库关联
		for _, knowledgeId := range appForm.KnowledgeId {
			appKnowledgeRelate := application.AppKnowledgeRelate{
				AppId:       appId,
				KnowledgeId: knowledgeId,
			}
			if err := appKnowledgeRelate.Create(tx); err != nil {
				glog.Error(err)
				c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
				return err
			}
		}
		return nil
	})

	c.JSON(http.StatusOK, common.SuccessResponse(""))
}
func DeleteApp(c *gin.Context) {
	//li, exists := c.Get(authorization.LoginUserKey)
	//if !exists {
	//	c.AbortWithStatusJSON(common.ErrorResponse("get user from context failed"))
	//	return
	//}
	//current := li.(*model.User)

	appIdStr := c.Param("appId")
	appId, err := strconv.Atoi(appIdStr)
	if err != nil {
		c.AbortWithStatusJSON(common.ErrorResponse("invalid app ID"))
		return
	}

	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}

	db.Transaction(func(tx *gorm.DB) error {
		app := application.Application{
			Id: appId,
		}
		if err := app.Delete(tx); err != nil {
			glog.Error(err)
			c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
			return err
		}

		// 删除知识库关联
		if err := tx.Where("app_id = ?", appId).Delete(&application.AppKnowledgeRelate{}).Error; err != nil {
			glog.Error(err)
			c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
			return err
		}
		return nil
	})

	c.JSON(http.StatusOK, common.SuccessResponse(""))
}
func GetAppList(c *gin.Context) {
	appList := []AppForm{}
	li, exists := c.Get(authorization.LoginUserKey)
	if !exists {
		c.AbortWithStatusJSON(common.ErrorResponse("get user from content failed"))
		return
	}
	current := li.(*model.User)
	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
	}
	app := application.Application{UserId: current.UserID}
	applications, err := app.GetListByUserId(db)
	if err != nil {
		if errors2.Is(err, gorm.ErrRecordNotFound) {
			c.JSON(http.StatusOK, common.SuccessResponse(appList))
			return
		}
		glog.Errorf("Get app list error: %v", err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}
	for _, a := range applications {
		relate := &application.AppKnowledgeRelate{AppId: a.Id}
		appKnowledgeRelates, _ := relate.GetListByAppId(db)
		knowledgeIds := []int{}
		for _, relate := range appKnowledgeRelates {
			knowledgeIds = append(knowledgeIds, relate.KnowledgeId)
		}
		appList = append(appList, AppForm{
			Application: a,
			KnowledgeId: knowledgeIds,
		})
	}
	c.JSON(http.StatusOK, common.SuccessResponse(appList))
}
func GetAppDetail(c *gin.Context) {
	appId := c.Param("appId")
	appIdInt, err := strconv.Atoi(appId)
	if err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse("invalid app ID"))
		return
	}
	//li, exists := c.Get(authorization.LoginUserKey)
	//if !exists {
	//	c.AbortWithStatusJSON(common.ErrorResponse("get user from content failed"))
	//	return
	//}
	//current := li.(*model.User)
	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}

	// 获取应用基本信息
	app := application.Application{Id: appIdInt}
	err = app.GetById(db)
	if err != nil {
		if errors2.Is(err, gorm.ErrRecordNotFound) {
			c.AbortWithStatusJSON(common.ErrorResponse("Application not found"))
			return
		}
		glog.Errorf("Get app detail error: %v", err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}
	//if app.UserId != current.UserID {
	//	c.AbortWithStatusJSON(common.ErrorResponse("Permission denied"))
	//	return
	//}

	// 获取应用关联的知识库ID列表
	relate := &application.AppKnowledgeRelate{AppId: appIdInt}
	appKnowledgeRelates, err := relate.GetListByAppId(db)
	if err != nil {
		glog.Errorf("Get app detail error: %v", err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}
	knowledgeIds := []int{}
	for _, relate := range appKnowledgeRelates {
		knowledgeIds = append(knowledgeIds, relate.KnowledgeId)
	}

	// 构建响应数据
	appDetail := AppForm{
		Application: app,
		KnowledgeId: knowledgeIds,
	}

	c.JSON(http.StatusOK, common.SuccessResponse(appDetail))
} // ...existing code...

func CreateDefaultKbHandler(c *gin.Context) {
	// const testUserId = "zzp"
	// 获取当前登录用户
	li, exists := c.Get(authorization.LoginUserKey)
	if !exists {
		c.AbortWithStatusJSON(common.ErrorResponse("get user from content failed"))
		return
	}
	current := li.(*model.User)

	// 请求参数结构体
	type CreateKnowledgeReq struct {
		Name        string `json:"name" binding:"required"`
		Description string `json:"description" binding:"-"`
	}

	var req CreateKnowledgeReq
	if err := c.ShouldBindJSON(&req); err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse("invalid request parameters"))
		return
	}

	// 获取数据库连接
	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}
	shortUid := strings.ToLower(strings.Replace(current.UserID[:len(current.UserID)-4], "UID-", "", 1))
	// 调用CreateDefaultKb创建知识库
	kbId, err := utils.CreateDefaultKb(shortUid, req.Name)
	if err != nil {
		glog.Errorf("Create default kb error: %v", err)
		c.AbortWithStatusJSON(common.ErrorResponse("create knowledge base failed"))
		return
	}

	// 创建知识库记录
	knowledge := &application.Knowledge{
		Name:        req.Name,
		Description: req.Description,
		Type:        1,
		KnowledgeId: kbId,
		CreatedAt:   time.Now(),
		UpdatedAt:   time.Now(),
	}

	if err := knowledge.Create(db); err != nil {
		glog.Errorf("Save knowledge base error: %v", err)
		c.AbortWithStatusJSON(common.ErrorResponse("save knowledge base failed"))
		return
	}

	c.JSON(http.StatusOK, common.SuccessResponse(knowledge))
}

// 常量定义
const (
	MaxFileSize   = 50 * 1024 * 1024  // 单文件最大50MB
	MaxTotalFiles = 10                // 最大文件数
	MaxTotalSize  = 200 * 1024 * 1024 // 总大小200MB
	AllowedTypes  = ".txt,.doc,.docx,.pdf,.ppt,.pptx,.xls,.xlsx"
)

// 错误信息
var (
	ErrNoFiles           = "未上传任何文件"
	ErrTooManyFiles      = "文件数量超过限制(%d个)"
	ErrFileTooLarge      = "文件 %s 超过大小限制(50MB)"
	ErrTotalSizeTooLarge = "总文件大小超过限制(200MB)"
	ErrInvalidFileType   = "不支持的文件类型: %s"
)

// 知识库文件上传
func UploadFilesToKbHandler(c *gin.Context) {
	// 获取用户信息
	li, exists := c.Get(authorization.LoginUserKey)
	if !exists {
		c.AbortWithStatusJSON(common.ErrorResponse("获取用户信息失败"))
		return
	}
	current := li.(*model.User)
	// _ = li.(*model.User)
	// const testUserId = "zzp"
	shortUid := strings.ToLower(strings.Replace(current.UserID[:len(current.UserID)-4], "UID-", "", 1))
	// 获取请求参数
	knowledgeId := c.PostForm("kb_id")
	if knowledgeId == "" {
		c.AbortWithStatusJSON(common.ErrorResponse("未提供知识库ID"))
		return
	}
	mode := c.DefaultPostForm("mode", "soft")
	chunkSize, _ := strconv.Atoi(c.DefaultPostForm("chunk_size", "800"))

	// 获取并验证文件
	form, _ := c.MultipartForm()
	var files []*multipart.FileHeader
	// 遍历所有文件字段
	for _, fileHeaders := range form.File {
		files = append(files, fileHeaders...)
	}
	if len(files) == 0 {
		c.AbortWithStatusJSON(common.ErrorResponse(ErrNoFiles))
		return
	}
	if len(files) > MaxTotalFiles {
		c.AbortWithStatusJSON(common.ErrorResponse(fmt.Sprintf(ErrTooManyFiles, MaxTotalFiles)))
		return
	}

	// 验证文件大小和类型
	var totalSize int64
	for _, file := range files {
		if file.Size > MaxFileSize {
			c.AbortWithStatusJSON(common.ErrorResponse(fmt.Sprintf(ErrFileTooLarge, file.Filename)))
			return
		}
		totalSize += file.Size

		ext := strings.ToLower(filepath.Ext(file.Filename))
		if !strings.Contains(AllowedTypes, ext) {
			c.AbortWithStatusJSON(common.ErrorResponse(fmt.Sprintf(ErrInvalidFileType, ext)))
			return
		}
	}
	if totalSize > MaxTotalSize {
		c.AbortWithStatusJSON(common.ErrorResponse(ErrTotalSizeTooLarge))
		return
	}

	var fileDataList []utils.FileData
	var mutex sync.Mutex
	errChan := make(chan error, len(files))
	var wg sync.WaitGroup

	for _, file := range files {
		wg.Add(1)
		go func(file *multipart.FileHeader) {
			defer wg.Done()

			f, err := file.Open()
			if err != nil {
				errChan <- fmt.Errorf("打开文件失败 %s: %v", file.Filename, err)
				return
			}

			mutex.Lock()
			fileDataList = append(fileDataList, utils.FileData{
				Reader:   f,
				Filename: file.Filename,
			})
			mutex.Unlock()
		}(file)
	}

	// 等待所有文件处理完成
	wg.Wait()
	close(errChan)

	// 检查错误
	for err := range errChan {
		if err != nil {
			c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
			return
		}
	}

	// 上传文件到知识库
	resp, err := utils.UploadFilesToKb(shortUid, knowledgeId, fileDataList, mode, chunkSize)
	if err != nil {
		c.AbortWithStatusJSON(common.ErrorResponse("上传文件失败"))
		return
	}

	c.JSON(http.StatusOK, common.SuccessResponse(map[string]interface{}{
		"knowledge_id": knowledgeId,
		"files":        resp.Data,
		"total_size":   totalSize,
		"file_count":   len(fileDataList),
		"msg":          resp.Msg,
	}))
}

func ListKnowledgeBaseHandler(c *gin.Context) {
	// 获取当前登录用户
	li, exists := c.Get(authorization.LoginUserKey)
	if !exists {
		c.AbortWithStatusJSON(common.ErrorResponse("get user from content failed"))
		return
	}
	current := li.(*model.User)
	// _ = li.(*model.User)
	// const testUserId = "zzp"
	// 获取远程知识库列表
	shortUid := strings.ToLower(strings.Replace(current.UserID[:len(current.UserID)-4], "UID-", "", 1))
	kbs, err := utils.ListKnowledgeBase(shortUid)
	if err != nil {
		glog.Errorf("List knowledge base error: %v", err)
		c.AbortWithStatusJSON(common.ErrorResponse("list knowledge base failed"))
		return
	}

	// 获取数据库连接
	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}

	// 补充知识库信息
	result := make([]map[string]interface{}, 0)
	for _, kb := range kbs {
		item := map[string]interface{}{
			"kb_id": kb.KbId,
			"name":  kb.KbName,
		}

		// 查询补充信息
		var knowledge application.Knowledge
		if err := db.Where("knowledge_id = ?", kb.KbId).First(&knowledge).Error; err == nil {
			item["description"] = knowledge.Description
			item["type"] = knowledge.Type
			item["created_at"] = knowledge.CreatedAt
			item["updated_at"] = knowledge.UpdatedAt
		}

		result = append(result, item)
	}

	c.JSON(http.StatusOK, common.SuccessResponse(result))
}

type ListKnowledgeBaseFilesRequest struct {
	KbId string `json:"kb_id" binding:"required"`
}

func ListKnowledgeBaseFilesHandler(c *gin.Context) {
	// 获取当前登录用户
	li, exists := c.Get(authorization.LoginUserKey)
	if !exists {
		c.AbortWithStatusJSON(common.ErrorResponse("get user from content failed"))
		return
	}
	current := li.(*model.User)
	// _ = li.(*model.User)
	// const testUserId = "zzp"
	shortUid := strings.ToLower(strings.Replace(current.UserID[:len(current.UserID)-4], "UID-", "", 1))
	// 解析请求体
	var req ListKnowledgeBaseFilesRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.AbortWithStatusJSON(common.ErrorResponse("invalid request body"))
		return
	}

	// 获取知识库文件列表
	files, err := utils.ListKnowledgeBaseFiles(shortUid, req.KbId)
	if err != nil {
		glog.Errorf("List knowledge base files error: %v", err)
		c.AbortWithStatusJSON(common.ErrorResponse("list knowledge base files failed"))
		return
	}

	c.JSON(http.StatusOK, common.SuccessResponse(files.Data))
}

// 删除文件的请求结构体
type DeleteKnowledgeBaseFilesRequest struct {
	KbId    string   `json:"kb_id" binding:"required"`
	FileIds []string `json:"file_ids" binding:"required"`
}

// DeleteKnowledgeBaseFilesHandler 处理删除知识库文件的请求
func DeleteKnowledgeBaseFilesHandler(c *gin.Context) {
	// 获取当前登录用户
	li, exists := c.Get(authorization.LoginUserKey)
	if !exists {
		c.AbortWithStatusJSON(common.ErrorResponse("get user from content failed"))
		return
	}
	current := li.(*model.User)
	//
	shortUid := strings.ToLower(strings.Replace(current.UserID[:len(current.UserID)-4], "UID-", "", 1))

	// 解析请求体
	var req DeleteKnowledgeBaseFilesRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.AbortWithStatusJSON(common.ErrorResponse("invalid request body"))
		return
	}

	// 删除文件
	resp, err := utils.DeleteKnowledgeBaseFiles(shortUid, req.KbId, req.FileIds)
	if err != nil {
		glog.Errorf("Delete knowledge base files error: %v", err)
		c.AbortWithStatusJSON(common.ErrorResponse("delete knowledge base files failed"))
		return
	}

	c.JSON(http.StatusOK, common.SuccessResponse(resp))
}

// CleanFilesByStatusRequest 定义清理文件请求结构
type CleanFilesByStatusRequest struct {
	Status string   `json:"status" binding:"required"`
	KbIds  []string `json:"kb_ids"`
}

// CleanFilesByStatusHandler 处理清理知识库文件的请求
func CleanFilesByStatusHandler(c *gin.Context) {
	// 获取当前登录用户
	li, exists := c.Get(authorization.LoginUserKey)
	if !exists {
		c.AbortWithStatusJSON(common.ErrorResponse("get user from content failed"))
		return
	}
	current := li.(*model.User)
	// _ = li.(*model.User)
	// const testUserId = "zzp"
	shortUid := strings.ToLower(strings.Replace(current.UserID[:len(current.UserID)-4], "UID-", "", 1))
	// 解析请求体
	var req CleanFilesByStatusRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.AbortWithStatusJSON(common.ErrorResponse("invalid request body"))
		return
	}

	// 验证状态值是否合法
	validStatus := map[string]bool{
		"red":    true,
		"green":  true,
		"yellow": true,
		"gray":   true,
	}
	if !validStatus[req.Status] {
		c.AbortWithStatusJSON(common.ErrorResponse("invalid status value"))
		return
	}

	// 清理文件
	resp, err := utils.CleanFilesByStatus(shortUid, req.Status, req.KbIds)
	if err != nil {
		glog.Errorf("Clean files by status error: %v", err)
		c.AbortWithStatusJSON(common.ErrorResponse("clean files failed"))
		return
	}

	c.JSON(http.StatusOK, common.SuccessResponse(resp))
}

func httpPost(url string, jsonData []byte) (string, error) {
	// 要发送POST请求的URL
	//url := "http://example.com/post"

	// 要发送的数据，这里以JSON格式为例
	//jsonData := []byte(`{
	//	"key1": "value1",
	//	"key2": "value2"
	//}`)

	// 创建一个请求
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
	if err != nil {
		log.Fatal(err)
	}

	// 设置请求头，例如设置内容类型为JSON
	req.Header.Set("Content-Type", "application/json")

	// 发送请求
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

	// 读取响应
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	return string(body), nil
}

func CreateBot(userId string, botName string, setting string, welcomeMsg string, kbs []string) (string, error) {
	// 定义请求结构体，用于构造API请求参数
	req := struct {
		UserId     string   `json:"user_id"`
		BotName    string   `json:"bot_name"`
		Setting    string   `json:"prompt_setting"`
		WelcomeMsg string   `json:"welcome_message"`
		Kbs        []string `json:"kb_ids"`
	}{
		UserId:     userId,
		BotName:    botName,
		Setting:    setting,
		WelcomeMsg: welcomeMsg,
		Kbs:        kbs,
	}
	// 将请求结构体转换为JSON格式
	body, err := json.Marshal(req)
	if err != nil {
		glog.Error(err)
		return "", err
	}
	// 发送HTTP POST请求到机器人创建API
	strBody, err := httpPost("http://192.168.2.37:8777/api/local_doc_qa/new_bot", body)
	if err != nil {
		glog.Error(err)
		return "", err
	}
	//{"code":200,"msg":"success create qanything bot BOTbfb8eff851994dd9a9f5d7457ba8f779","data":{"bot_id":"BOTbfb8eff851994dd9a9f5d7457ba8f779","bot_name":"\u5510\u50e7","create_time":"2024-12-08 22:52:57"}}
	var botResponse struct {
		Code int    `json:"code"`
		Msg  string `json:"msg"`
		Data struct {
			BotId   string `json:"bot_id"`
			BotName string `json:"bot_name"`
		} `json:"data"`
	}

	if err := json.Unmarshal([]byte(strBody), &botResponse); err != nil {
		glog.Error(err)
		return "", err
	}
	return botResponse.Data.BotId, nil
}

//	{
//	 "user_id": "zzpp",
//	 "bot_id": "BOT3efc84c4fae54cb0ad84f7f598a5d83c",
//	 "bot_name": "孙悟空",
//	 "api_base": "https://dashscope.aliyuncs.com/compatible-mode/v1",
//	 "api_key": "sk-1ee9a7e65dd64279971c6e6a67c1731d",
//	 "api_context_length": 16384,
//	 "prompt_setting": "- 你是孙悟空，一个耐心、友好、专业的数字人，能够回答用户的各种问题，如果用户问你的身份，你要回答你是孙悟空。- 根据知识库内的检索结果，以清晰简洁的表达方式回答问题。- 不要编造答案，如果答案不在经核实的资料中或无法从经核实的资料中得出，请回答“我无法回答您的问题。”（或者您可以修改为：如果给定的检索结果无法回答问题，可以利用你的知识尽可能回答用户的问题。)",
//	 "top_p": 1,
//	 "top_k": 5,
//	 "chunk_size": 800,
//	 "temperature": 0.5,
//	 "model": "qwen-plus",
//	 "max_token": 512,
//	 "rerank": false,
//	 "hybrid_search": true,
//	 "networking": false,
//	 "only_need_search_results": false
//	}
type UpdateBotReq struct {
	UserId                string  `json:"user_id"`
	BotId                 string  `json:"bot_id"`
	BotName               string  `json:"bot_name"`
	ApiBase               string  `json:"api_base"`
	ApiKey                string  `json:"api_key"`
	ApiContext            int     `json:"api_context_length"`
	Setting               string  `json:"prompt_setting"`
	TopP                  float64 `json:"top_p"`
	TopK                  int     `json:"top_k"`
	ChunkSize             int     `json:"chunk_size"`
	Temperature           float64 `json:"temperature"`
	Model                 string  `json:"model"`
	MaxToken              int     `json:"max_token"`
	Rerank                bool    `json:"rerank"`
	HybridSearch          bool    `json:"hybrid_search"`
	Networking            bool    `json:"networking"`
	OnlyNeedSearchResults bool    `json:"only_need_search_results"`
}

func UpdateBot(up UpdateBotReq) error {
	up.ApiContext = 16384
	up.MaxToken = 512
	up.ChunkSize = 800
	up.Temperature = 0.5
	up.TopP = 1
	up.TopK = 5
	up.Rerank = false
	up.HybridSearch = true
	up.Networking = false
	up.OnlyNeedSearchResults = false
	body, _ := json.Marshal(up)

	res, err := httpPost("http://192.168.2.37:8777/api/local_doc_qa/update_bot", body)
	if err != nil {
		glog.Error(err)
		return err
	}
	fmt.Println(res)
	return nil
}

func DeleteKbHandler(c *gin.Context) {
	// 获取当前登录用户
	li, exists := c.Get(authorization.LoginUserKey)
	if !exists {
		c.AbortWithStatusJSON(common.ErrorResponse("get user from content failed"))
		return
	}
	current := li.(*model.User)
	shortUid := strings.ToLower(strings.Replace(current.UserID[:len(current.UserID)-4], "UID-", "", 1))
	// 请求参数结构体
	type DeleteKnowledgeReq struct {
		KnowledgeId string `json:"knowledge_id" binding:"required"`
	}

	var req DeleteKnowledgeReq
	if err := c.ShouldBindJSON(&req); err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse("invalid request parameters"))
		return
	}

	// 获取数据库连接
	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}

	// 调用DeleteKnowledgeBase删除远程知识库
	resp, err := utils.DeleteKnowledgeBase(shortUid, []string{req.KnowledgeId})
	if err != nil {
		glog.Errorf("Delete knowledge base error: %v", err)
		c.AbortWithStatusJSON(common.ErrorResponse("delete knowledge base failed"))
		return
	}

	if resp.Code != 200 {
		glog.Errorf("Delete knowledge base failed: %s", resp.Msg)
		c.AbortWithStatusJSON(common.ErrorResponse(resp.Msg))
		return
	}

	// 从数据库中删除知识库记录
	if err := db.Where("knowledge_id = ?", req.KnowledgeId).Delete(&application.Knowledge{}).Error; err != nil {
		glog.Errorf("Delete knowledge record error: %v", err)
		c.AbortWithStatusJSON(common.ErrorResponse("delete knowledge record failed"))
		return
	}

	// 删除知识库关联关系
	if err := db.Where("knowledge_id = ?", req.KnowledgeId).Delete(&application.AppKnowledgeRelate{}).Error; err != nil {
		glog.Errorf("Delete knowledge relation error: %v", err)
		c.AbortWithStatusJSON(common.ErrorResponse("delete knowledge relation failed"))
		return
	}

	c.JSON(http.StatusOK, common.SuccessResponse(nil))
}

func RenameKbHandler(c *gin.Context) {
	// 获取当前登录用户
	li, exists := c.Get(authorization.LoginUserKey)
	if !exists {
		c.AbortWithStatusJSON(common.ErrorResponse("get user from content failed"))
		return
	}
	current := li.(*model.User)
	// _ = li.(*model.User)
	// const testUserId = "zzp"
	shortUid := strings.ToLower(strings.Replace(current.UserID[:len(current.UserID)-4], "UID-", "", 1))
	// 请求参数结构体
	type RenameKnowledgeReq struct {
		KnowledgeId string `json:"knowledge_id" binding:"required"`
		NewKbName   string `json:"new_kb_name" binding:"required"`
	}
	type RenameResponse struct {
		Message string `json:"message"`
	}
	var req RenameKnowledgeReq
	if err := c.ShouldBindJSON(&req); err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse("invalid request parameters"))
		return
	}

	// 获取数据库连接
	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}

	// 调用RenameKnowledgeBase重命名远程知识库
	resp, err := utils.RenameKnowledgeBase(shortUid, req.KnowledgeId, req.NewKbName)
	if err != nil {
		glog.Errorf("Rename knowledge base error: %v", err)
		c.AbortWithStatusJSON(common.ErrorResponse("rename knowledge base failed"))
		return
	}

	if resp.Code != 200 {
		glog.Errorf("Rename knowledge base failed: %s", resp.Msg)
		c.AbortWithStatusJSON(common.ErrorResponse(resp.Msg))
		return
	}

	// 更新数据库中的知识库名称
	if err := db.Model(&application.Knowledge{}).
		Where("knowledge_id = ?", req.KnowledgeId).
		Update("name", req.NewKbName).Error; err != nil {
		glog.Errorf("Update knowledge name error: %v", err)
		c.AbortWithStatusJSON(common.ErrorResponse("update knowledge name failed"))
		return
	}

	c.JSON(http.StatusOK, common.SuccessResponse(RenameResponse{
		Message: resp.Msg,
	}))
}
